package com.syg.rabbitmq.consumer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;


/**
 * <img width="宽度" height="高度" src="" alt="">
 */
public class Consumer {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        // 为什么这里声明虚拟主机会报错呢？
        factory.setVirtualHost("/");

        //这里不使用try-with-resource，因为消费者是一直等待新的消息到来，然后按照
        //我们设定的逻辑进行处理，所以这里不能在定义完成之后就关闭连接
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        /**
         * basicConsume方法参数如下：
         *      queue  -  消息队列名称，直接指定。
         *      autoAck - 自动应答，消费者从消息队列取出数据后，需要跟服务器进行确认应答，当服务器收到确认后，会自动将消息删除，如果开启自动应答，那么消息发出后会直接删除。
         *      deliver  -  消息接收后的函数回调，我们可以在回调中对消息进行处理，处理完成后，需要给服务器确认应答。
         *      cancel  -  当消费者取消订阅时进行的函数回调，这里暂时用不到。
         */
        channel.basicConsume("yyds", false, (s, delivery) -> {
            System.out.println(new String(delivery.getBody()));
            //basicAck是确认应答，第一个参数是当前的消息标签，后面的参数是
            //是否批量处理消息队列中所有的消息，如果为false表示只处理当前消息
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
            //basicNack是拒绝应答，最后一个参数表示是否将当前消息放回队列，如果
            //为false，那么消息就会被丢弃
            //channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false);
            //跟上面一样，最后一个参数为false，只不过这里省了
            //channel.basicReject(delivery.getEnvelope().getDeliveryTag(), false);
        }, s -> {});
    }
}
